{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Problem: Visualize Training Progress with TensorBoard in PyTorch\n",
    "\n",
    "### Problem Statement\n",
    "You are tasked with using **TensorBoard** to monitor the training progress of a linear regression model in PyTorch. TensorBoard provides a visual interface to track metrics such as loss during training, making it easier to analyze and debug your model.\n",
    "\n",
    "### Requirements\n",
    "1. **TensorBoard Integration**:\n",
    "   - Set up TensorBoard using `torch.utils.tensorboard.SummaryWriter`.\n",
    "   - Log the training loss after each epoch.\n",
    "\n",
    "4. **Visualization**:\n",
    "   - Start TensorBoard using the command:  \n",
    "     ```bash\n",
    "     tensorboard --logdir=runs\n",
    "     ```\n",
    "   - Visualize the loss curve during training.\n",
    "\n",
    "### Constraints\n",
    "- Ensure that TensorBoard logs are saved in a directory named `runs`.\n",
    "- The solution must handle multiple epochs and log the loss consistently.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from torch.utils.tensorboard import SummaryWriter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Generate synthetic data\n",
    "torch.manual_seed(42)\n",
    "X = torch.rand(100, 1) * 10  # 100 data points between 0 and 10\n",
    "y = 3 * X + 5 + torch.randn(100, 1)  # Linear relationship with noise\n",
    "\n",
    "# Define a simple Linear Regression Model\n",
    "class LinearRegressionModel(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(LinearRegressionModel, self).__init__()\n",
    "        self.linear = nn.Linear(1, 1)  # Single input and single output\n",
    "\n",
    "    def forward(self, x):\n",
    "        return self.linear(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize TensorBoard writer\n",
    "writer = SummaryWriter(log_dir=\"runs/linear_regression\")\n",
    "\n",
    "# Initialize the model, loss function, and optimizer\n",
    "model = LinearRegressionModel()\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = optim.SGD(model.parameters(), lr=0.01)\n",
    "\n",
    "# Training loop\n",
    "epochs = 100\n",
    "for epoch in range(epochs):\n",
    "    # Forward pass\n",
    "    predictions = model(X)\n",
    "    loss = criterion(predictions, y)\n",
    "\n",
    "    # Backward pass and optimization\n",
    "    optimizer.zero_grad()\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "\n",
    "    # Log loss to TensorBoard\n",
    "    writer.add_scalar(\"Loss/train\", loss.item(), epoch)\n",
    "\n",
    "    # Log progress every 10 epochs\n",
    "    if (epoch + 1) % 10 == 0:\n",
    "        print(f\"Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}\")\n",
    "\n",
    "# Close the TensorBoard writer\n",
    "writer.close()\n",
    "\n",
    "# Run TensorBoard using the logs generated\n",
    "# Command to run: tensorboard --logdir=runs\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
